package org.aner.tester.resolver;

import org.aner.tester.object.ValueObject;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * field resolver of object
 *
 * @author aner
 * @version 1.0
 * @date 2020/12/16 13:17
 */
public class FieldResolver {

    /**
     * resolve field of object
     *
     * @param field
     * @param levelCount
     * @return
     */
    public static ValueObject resolve(Field field, int levelCount) {
        ValueObject valueObject = new ValueObject();
        valueObject.setLevelCount(levelCount);
        Type type =  field.getGenericType();
        String typeName = field.getType().getName();
        String simpleTypeName = field.getType().getSimpleName();
        String genericTypeName = type.getTypeName();
        // basic、 custom、list(without generic) type
        if (typeName.equals(genericTypeName)) {
            valueObject.setGenericCollection(false);
            valueObject.setSimpleTypeName(simpleTypeName);
            valueObject.setTypeName(typeName);
            // array and list(with generic) type
        } else {
            valueObject.setGenericCollection(true);
            if(ResolverFactory.isArray(genericTypeName)) {
                valueObject.setTypeName(ResolverFactory.getArrayTypeName(genericTypeName));
                valueObject.setSimpleTypeName(ResolverFactory.getArrayTypeName(genericTypeName));
                valueObject.setGenericTypeNameList(Arrays.asList(ResolverFactory.getArrayGenericName(genericTypeName)));
            } else {
                valueObject.setTypeName(typeName);
                valueObject.setSimpleTypeName(simpleTypeName);
                valueObject.setGenericTypeNameList(Arrays.asList(ResolverFactory.getCollectionGenericName(genericTypeName)));
            }
            valueObject.setGenericTypeSimpleNameList(valueObject.getGenericTypeNameList().stream().map(ResolverFactory::getTypeSimpleName).collect(Collectors.toList()));
        }
        return valueObject;
    }
}
